/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Player;

import Biblioteca.Cancion;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Random;

/**
 * Clase que implementa el comportamiento de una lista de reproduccion
 * @author IS G2
 */
public class ListaReproduccion {

    /**
     * Indica si está activa la función repeatAll
     */
    private boolean repetirTodas;
    /**
     * Representa la lista de canciones.
     */
    private ArrayList<Cancion> listaArchivos;
    /**
     * Representa la lista de reproducción actual. Contiene los indices de las canciones de listaArchivos.
     */
    private ArrayList<Cancion> listaReproduccion;
    /**
     * Indice actual en la lista de reproducción
     */
    private int indice;
    
    /**
     * Constructora por defecto
     */
    public ListaReproduccion() {
        listaArchivos = new ArrayList<Cancion>();
        listaReproduccion = new ArrayList<Cancion>();
        indice = 0;
        repetirTodas = false;
    }

    /**
     * Añade una canción a la lista
     * @param cancion
     */
    public void aniadirCancion(Cancion cancion) {
        listaArchivos.add(cancion);
        listaReproduccion.add(cancion);
    }

    /**
     * Añade una cancion aleatoriamente entre la actual y el final de la lista
     * @param cancion
     */
    public void aniadirCancionAleatoriamente(Cancion cancion) {
        Random r;
        r = new Random();
        r.setSeed(new Date().getTime());
        int pos = r.nextInt(tamanio() - indice) + indice;
        listaReproduccion.add(pos, cancion);
        listaArchivos.add(cancion);
    }

    /**
     * Elimina una canción de la lista
     * @param cancion
     */
    public void eliminarCancion(Cancion cancion) {
        if (!listaArchivos.isEmpty()) {
            /*
             * Si borramos la cancion actual, ponemos la siguiente
             */
            if (indice == listaReproduccion.indexOf(cancion)) {
                cancionSiguiente();
            }
            listaReproduccion.remove(cancion);
            listaArchivos.remove(cancion);
            indice--;
        }
    }

    /**
     * Elimina la cancion de la lista que se encuentra en la posicion index
     * @param index
     */
    public void eliminarCancion(int index) {
        if (!listaArchivos.isEmpty()) {
            Cancion cancion = listaArchivos.get(index);
            listaReproduccion.remove(cancion);
            listaArchivos.remove(cancion);
            indice--;
        }
    }

    /**
     * Devuelve el tamaño de la lista de reproducción
     * @return int
     */
    public int tamanio() {
        return listaArchivos.size();
    }

    /**
     * Devuelve la cancion siguiente, null si no hay siguiente.
     * @return Cancion
     */
    public Cancion cancionSiguiente() {
        /**
         * Si el índice está fuera de rango no devuelve nada. Si el indice apunta a al ultimo elemento y está 
         * activado repetirTodas se pone al principio de la lista, sino devuelve null porque termina la lista.
         * En el resto de los casos avanza a la siguiente.
         */
        if (tamanio() == 0 || indice < 0 || indice >= tamanio()) {
            return null;
        } else if (indice == tamanio() - 1) {
            if (repetirTodas) {
                indice = 0;
            } else {
                indice = tamanio();
                return null;
            }

        } else {
            indice++;
        }
        return listaReproduccion.get(indice);
    }

    /**
     * Devuelve la cancion anterior, null si no hay anterior.
     * @return Cancion
     */
    public Cancion cancionAnterior() {
        if (tamanio() == 0 || indice < 0 || indice > tamanio()) {
            return null;
        } else if (indice == 0) {
            return listaReproduccion.get(indice);
        } else {
            indice--;
            return listaReproduccion.get(indice);
        }
    }

    /**
     * Devuelve la cancion actual
     * @return Cancion
     */
    public Cancion cancionActual() {
        if (!listaArchivos.isEmpty()) {
            if (indice >= tamanio() || indice < 0) {
                return null;
            }
            return listaReproduccion.get(indice);
        } else {
            return null;
        }
    }

    /**
     * Devuelve la cancion en la posicion i de la lista y actualiza el señalador
     * @param index
     * @return Cancion
     */
    public Cancion saltarACancionSeleccionada(int index) {
        Cancion cancion = listaArchivos.get(index);
        indice = listaReproduccion.indexOf(cancion);
        return cancion;
    }

    /**
     * Devuelve la cancion seleccionada en index
     * @param index
     * @return
     */
    public Cancion dameCancion(int index) {
        return listaArchivos.get(index);
    }

    /**
     * Ordena la lista de reproduccion de forma aleatoria poniendo como primera la cancion actual
     */
    public void mezclarListaNueva() {
        if (tamanio() > 0) {
            Random r;
            r = new Random();

            r.setSeed(new Date().getTime());
            Cancion cancion = cancionActual();
            if (cancion != null) {
                listaReproduccion.remove(cancion);
                Collections.shuffle(listaReproduccion, r);
                listaReproduccion.add(0, cancion);
            } else {
                Collections.shuffle(listaReproduccion, r);
            }
            indice = 0;
        }
    }

    /**
     * Ordena la lista de reproduccion por su orden original
     */
    public void secuenciarLista() {
        if (tamanio() > 0) {
            Cancion cancionSeleccionada = listaReproduccion.get(indice);
            listaReproduccion = new ArrayList<Cancion>();
            for (int i = 0; i < listaArchivos.size(); i++) {
                listaReproduccion.add(listaArchivos.get(i));
            }
            indice = listaReproduccion.indexOf(cancionSeleccionada);
        }
    }

    /**
     * Devuelve el índice actual en la lista de reproduccion
     * @return
     */
    public int getIndice(){
        return indice;
    }

    /**
     * Cambia el valor de repeatAll por el del parametro
     * @param valor
     */
    public void setRepeatAll(boolean valor) {
        repetirTodas = valor;
    }
}
